﻿using IOP.SgrA;
using IOP.SgrA.ECS;
using IOP.SgrA.Input;
using Microsoft.Extensions.Options;
using System;
using System.Collections.Generic;
using System.Numerics;
using System.Text;

namespace VkSample412
{
    public class TransformSystem : ComponentSystem
    {

        private Matrix4x4 ProjectM;

        private float AngleX = 90.0f;
        private float AngleZ = 20.0f;
        private bool ProjectPara;
        private float Aspect;
        private float NEARt = 1.0f;
        private bool NeedChange;

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="contextManager"></param>
        public TransformSystem()
        {
        }

        public override void Initialization()
        {
            var area = Owner.Area;
            int x = 250;
            Aspect = area.Width / area.Height;
            ProjectM = Matrix4x4.CreatePerspectiveOffCenter(-NEARt * Aspect * 0.25f, NEARt * Aspect * 0.25f, -NEARt * 0.25f, NEARt * 0.25f, NEARt, 10000.0f);
            ContextManager.Foreach<Group>((group) =>
            {
                Context context = ContextManager.GetContext(group.Entity);
                context.SetProjectionMatrix(ProjectM);
                group.Transform.Position = new Vector3(x, 0, 0);
                x -= 500;
                return group;
            });
        }

        public override void Update(TimeSpan timeSpan)
        {
            float diffX = 0;
            float diffY = 0;
            if(Input.GetMouseButtonState(MouseButton.ButtonLeft).Action == InputAction.Press)
            {
                Vector2 p = Input.GetMousePositionDelta();
                diffX = p.X;
                diffY = p.Y;
            }
            else if(Input.GetMouseButtonState(MouseButton.ButtonLeft).Action == InputAction.Click)
            {
                ProjectPara = !ProjectPara;
                if (ProjectPara)
                {
                    NEARt = 800;
                    ProjectM = Matrix4x4.CreatePerspectiveOffCenter(-NEARt * Aspect * 0.25f, NEARt * Aspect * 0.25f, -NEARt * 0.25f, NEARt * 0.25f, NEARt, 10000.0f);
                }
                else
                {
                    NEARt = 1;
                    ProjectM = Matrix4x4.CreatePerspectiveOffCenter(-NEARt * Aspect * 0.25f, NEARt * Aspect * 0.25f, -NEARt * 0.25f, NEARt * 0.25f, NEARt, 10000.0f);
                }
                NeedChange = true;
            }
            AngleX += diffX * 180 / 200;
            AngleZ += diffY * 180 / 200;
            ContextManager.Foreach<Group>((group) =>
            {
                Context context = ContextManager.GetContext(group.Entity);
                ref MVPMatrix mvp = ref context.GetMVPMatrix();
                mvp.ModelMatrix = Matrix4x4.CreateTranslation(group.Transform.Position) *
                Matrix4x4.CreateRotationY(AngleX / 180.0f * MathF.PI) *
                Matrix4x4.CreateRotationZ(AngleZ / 180.0f * MathF.PI);
                if (NeedChange)
                {
                    context.SetProjectionMatrix(ProjectM);
                }
                context.PushToRenderGroup();
            });
            if (NeedChange) NeedChange = false;
        }

        public struct Group
        {
            public Entity Entity;
            public TransformComponent Transform;
        }
    }
}
